#ifndef _CAMERA_H
#define _CAMERA_H

#include "Common.h"
#include "Ray.h"
#include "Primitive.h"

namespace Pandora
{

	class CCamera
	{
	protected:
		CVector3 position;
		CVector3 direction;
		CVector3 up;
		float fovx, fovy;

		int outputWidth;
		int outputHeight;
	public:
		CCamera() : position(CVector3(0.0f, 0.0f, 0.0f)), direction(CVector3(0.0f, 0.0f, 0.0f)), up(CVector3(0.0f, 1.0f, 0.0f)), outputWidth(0), outputHeight(0) {}
		CCamera(int ow, int oh) : position(CVector3(0.0f, 0.0f, 0.0f)), direction(CVector3(0.0f, 0.0f, 0.0f)), up(CVector3(0.0f, 1.0f, 0.0f)), outputWidth(ow), outputHeight(oh), fovx(PI/4.0f), fovy(tanf(fovx * ((float)oh/(float)ow))) {}
		CCamera(CCamera& c) : position(c.GetPosition()), direction(c.GetDirection()), up(c.GetUp()), outputWidth(c.GetOutputWidth()), outputHeight(c.GetOutputHeight()), fovx(c.GetFOVX()), fovy(c.GetFOVY()) {}
		CCamera(CCamera* c) : position(c->GetPosition()), direction(c->GetDirection()), up(c->GetUp()), outputWidth(c->GetOutputWidth()), outputHeight(c->GetOutputHeight()), fovx(c->GetFOVX()), fovy(c->GetFOVY()) {}

		virtual void Init() = 0;
		virtual CAMERAS GetType() = 0;
		virtual void CalculateRayDirection(CRay& ray, float x, float y) = 0;

		CVector3& GetPosition() { return position; }
		CVector3& GetDirection() { return direction; }
		CVector3& GetUp() { return up; }
		float GetFOVX() { return fovx; }
		float GetFOVY() { return fovy; }
		int GetOutputWidth() { return outputWidth; }
		int GetOutputHeight() { return outputHeight; }

		void SetPosition(CVector3* pos) { position = *pos; }
		void SetPosition(CVector3& pos) { position = pos; }
		void SetPosition(float x, float y, float z) { position = CVector3(x, y, z); }
		void SetDirection(CVector3* dir) { direction = *dir; }
		void SetDirection(CVector3& dir) { direction = dir; }
		void SetDirection(float x, float y, float z) { direction = CVector3(x, y, z); }
		void SetUp(CVector3* t) { up = *t; }
		void SetUp(CVector3& t) { up = t; }
		void SetUp(float x, float y, float z) { up = CVector3(x, y, z); }
		void SetFOVX(float f) { fovx = f; }
		void SetFOVY(float f) { fovy = f; }
		void SetTarget(float x, float y, float z) { direction = CVector3(x, y, z) - position; }
		void SetTarget(CVector3* tar) { direction =  *tar - position; }
		void SetTarget(CVector3& tar) { direction =  tar - position; }
		void SetTarget(CPrimitive* prim) { direction = prim->GetPosition() - position; }
		void SetTarget(CPrimitive& prim) { direction = prim.GetPosition() - position; }
	};

}; //namespace Pandora

#endif /* _CAMERA_H */